const express = require('express');
const path = require('path');
const { ProjectConfig, AnalysisReport, testConnection } = require('./database');
const GitLabAPI = require('./gitlab-api');
const AIAnalysisEngine = require('./ai-engine');
const GitAnalyzer = require('./git-analyzer');

const app = express();
const PORT = 3001;

// 中间件
app.use(express.json());
app.use(express.static('.'));

// 测试数据库连接
testConnection();

// API路由

// 获取所有项目配置
app.get('/api/configs', async (req, res) => {
  try {
    const configs = await ProjectConfig.findAll();
    res.json(configs);
  } catch (error) {
    console.error('获取配置失败:', error);
    res.status(500).json({ error: '获取配置失败' });
  }
});

// 根据ID获取项目配置
app.get('/api/configs/:id', async (req, res) => {
  try {
    const config = await ProjectConfig.findByPk(req.params.id);
    if (config) {
      res.json(config);
    } else {
      res.status(404).send('Config not found');
    }
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});

// 创建新的项目配置
app.post('/api/configs', async (req, res) => {
  try {
    // 确保新创建的配置有默认的连接状态
    const configData = {
      ...req.body,
      connectionStatus: 'untested'
    };
    const config = await ProjectConfig.create(configData);
    res.status(201).json(config);
  } catch (error) {
    console.error('创建配置失败:', error);
    res.status(500).json({ error: '创建配置失败' });
  }
});

// 更新项目配置
app.put('/api/configs/:id', async (req, res) => {
  try {
    const config = await ProjectConfig.findByPk(req.params.id);
    if (config) {
      await config.update(req.body);
      res.json(config);
    } else {
      res.status(404).json({ error: '配置未找到' });
    }
  } catch (error) {
    console.error('更新配置失败:', error);
    res.status(500).json({ error: '更新配置失败' });
  }
});

// 删除项目配置
app.delete('/api/configs/:id', async (req, res) => {
  try {
    const config = await ProjectConfig.findByPk(req.params.id);
    if (config) {
      await config.destroy();
      res.status(204).send();
    } else {
      res.status(404).json({ error: '配置未找到' });
    }
  } catch (error) {
    console.error('删除配置失败:', error);
    res.status(500).json({ error: '删除配置失败' });
  }
});

// 获取统计概览
app.get('/api/overview-stats', async (req, res) => {
  try {
    const totalProjects = await ProjectConfig.count();
    const totalReports = await AnalysisReport.count();
    const totalCommits = await AnalysisReport.sum('totalCommits');

    // 模拟平均处理时间
    const avgTime = 3.2;

    res.json({
      totalProjects,
      totalReports,
      totalCommits: totalCommits || 0,
      avgTime
    });
  } catch (error) {
    console.error('获取统计概览失败:', error);
    res.status(500).json({ error: '获取统计概览失败' });
  }
});

// 测试GitLab连接
app.post('/api/configs/:id/test-connection', async (req, res) => {
  try {
    const config = await ProjectConfig.findByPk(req.params.id);
    if (!config) {
      return res.status(404).json({ error: '配置未找到' });
    }

    // 这里应该实现真实的GitLab连接测试逻辑
    // 为演示目的，我们模拟连接测试
    const isConnected = await testGitLabConnection(config.gitlabUrl, config.accessToken);
    
    // 更新配置的连接状态
    const newStatus = isConnected ? 'connected' : 'disconnected';
    await config.update({
      connectionStatus: newStatus,
      lastTestedAt: new Date()
    });

    res.json({
      success: isConnected,
      status: newStatus,
      message: isConnected ? '连接成功' : '连接失败'
    });
  } catch (error) {
    console.error('测试连接失败:', error);
    res.status(500).json({ error: '测试连接失败' });
  }
});

// 真实的GitLab连接测试函数
async function testGitLabConnection(gitlabUrl, accessToken) {
  try {
    const gitlab = new GitLabAPI(gitlabUrl, accessToken);
    const connectionTest = await gitlab.testConnection();
    return connectionTest.success;
  } catch (error) {
    console.error('GitLab连接测试失败:', error);
    return false;
  }
}

// 获取所有报告
app.get('/api/reports', async (req, res) => {
  try {
    const reports = await AnalysisReport.findAll({
      order: [['generatedAt', 'DESC']]
    });
    res.json(reports);
  } catch (error) {
    console.error('获取报告列表失败:', error);
    res.status(500).json({ error: '获取报告列表失败' });
  }
});

// 根据ID获取分析报告
app.get('/api/reports/:id', async (req, res) => {
  try {
    const report = await AnalysisReport.findByPk(req.params.id);
    if (!report) {
      return res.status(404).json({ error: '报告未找到' });
    }
    
    // 如果报告正在生成中，返回状态信息
    if (report.status === 'generating') {
      return res.json({
        id: report.id,
        projectId: report.projectId,
        projectName: report.projectName,
        startDate: report.startDate,
        endDate: report.endDate,
        status: report.status,
        message: '报告正在生成中，请稍候...',
        generatedAt: report.generatedAt
      });
    }
    
    res.json(report);
  } catch (error) {
    console.error('获取报告失败:', error);
    res.status(500).json({ error: '获取报告失败' });
  }
});

// 创建新的分析报告
app.post('/api/reports', async (req, res) => {
  try {
    const { projectId, startDate, endDate } = req.body;
    
    if (!projectId || !startDate || !endDate) {
      return res.status(400).json({ error: '缺少必要参数：projectId, startDate, endDate' });
    }

    // 获取项目配置
    const config = await ProjectConfig.findByPk(projectId);
    if (!config) {
      return res.status(404).json({ error: '项目配置未找到' });
    }

    // 创建初始报告记录
    const report = await AnalysisReport.create({
      projectId,
      projectName: config.name,
      startDate,
      endDate,
      status: 'generating'
    });

    // 异步生成报告
    generateReportAsync(report.id, config, startDate, endDate);

    res.status(201).json({
      id: report.id,
      message: '报告生成已启动',
      status: 'generating'
    });
  } catch (error) {
    console.error('创建报告失败:', error);
    res.status(500).json({ error: '创建报告失败' });
  }
});

/**
 * 异步生成报告
 */
async function generateReportAsync(reportId, config, startDate, endDate) {
  try {
    console.log(`开始生成报告 ${reportId}`);
    console.log('配置信息:', {
      gitlabUrl: config.gitlabUrl,
      projectName: config.projectName,
      startDate,
      endDate
    });
    
    // 初始化GitLab API客户端，提取基础URL
    const baseUrl = extractBaseUrl(config.gitlabUrl);
    console.log('提取的基础URL:', baseUrl);
    const gitlab = new GitLabAPI(baseUrl, config.accessToken);
    
    // 测试连接，增加重试机制
    let connectionTest;
    let retries = 3;
    let useGitFallback = false;
    
    for (let i = 0; i < retries; i++) {
      try {
        connectionTest = await gitlab.testConnection();
        if (connectionTest.success) {
          console.log('GitLab连接成功，用户:', connectionTest.user.username);
          break;
        }
      } catch (error) {
        console.warn(`连接测试第 ${i + 1} 次失败:`, error.message);
        if (i < retries - 1) {
          await new Promise(resolve => setTimeout(resolve, 2000)); // 等待2秒后重试
        }
      }
    }
    
    if (!connectionTest || !connectionTest.success) {
      console.log('GitLab连接失败，准备使用git命令备用方案');
      useGitFallback = true;
    }
    
    // 获取提交数据
    let commits;
    
    if (useGitFallback) {
      // 使用git命令作为备用方案
      try {
        console.log('GitLab连接失败，使用git命令获取提交数据');
        const gitAnalyzer = new GitAnalyzer();
        
        // 检查是否为git仓库
        const isGitRepo = await gitAnalyzer.isGitRepository();
        if (isGitRepo) {
          commits = await gitAnalyzer.getCommitsCompatible(startDate, endDate);
          console.log(`通过git命令获取到 ${commits.length} 个提交`);
        } else {
          console.log('当前目录不是git仓库，使用模拟数据');
          commits = generateMockCommits(startDate, endDate);
        }
      } catch (gitError) {
        console.error('git命令也失败了:', gitError);
        console.log('使用模拟数据生成报告');
        commits = generateMockCommits(startDate, endDate);
      }
    } else {
      // 使用GitLab API
      try {
        commits = await gitlab.getAllCommits(config.projectName, {
          since: new Date(startDate).toISOString(),
          until: new Date(endDate + 'T23:59:59').toISOString()
        });
        console.log(`通过GitLab API获取到 ${commits.length} 个提交`);
      } catch (error) {
        console.error('GitLab API获取提交数据失败:', error);
        
        // GitLab API失败，尝试使用本地git命令作为备用方案
        try {
          console.log('GitLab API失败，尝试使用git命令获取提交数据');
          const gitAnalyzer = new GitAnalyzer();
          
          // 检查是否为git仓库
          const isGitRepo = await gitAnalyzer.isGitRepository();
          if (isGitRepo) {
            commits = await gitAnalyzer.getCommitsCompatible(startDate, endDate);
            console.log(`通过git命令获取到 ${commits.length} 个提交`);
          } else {
            console.log('当前目录不是git仓库，使用模拟数据');
            commits = generateMockCommits(startDate, endDate);
          }
        } catch (gitError) {
          console.error('git命令也失败了:', gitError);
          console.log('使用模拟数据生成报告');
          commits = generateMockCommits(startDate, endDate);
        }
      }
    }
    
    // 使用AI引擎分析提交
    const aiEngine = new AIAnalysisEngine();
    const analysis = await aiEngine.analyzeCommits(commits, config.name, startDate, endDate);
    
    console.log('AI分析完成');
    
    // 更新报告数据
    const report = await AnalysisReport.findByPk(reportId);
    if (!report) {
      throw new Error('报告记录不存在');
    }
    
    await report.update({
      totalCommits: analysis.totalCommits,
      features: analysis.commitTypes.feature,
      bugfixes: analysis.commitTypes.bugfix,
      refactorings: analysis.commitTypes.refactor,
      docs: analysis.commitTypes.docs,
      others: analysis.commitTypes.other + analysis.commitTypes.test + 
             analysis.commitTypes.style + analysis.commitTypes.chore,
      testCoverage: analysis.codeQuality.testCoverage,
      aiSummary: analysis.aiSummary,
      keyAchievements: analysis.keyAchievements,
      criticalBugfixes: analysis.criticalBugfixes,
      codeQuality: analysis.codeQuality,
      dailyCommits: analysis.dailyCommits,
      commitTypes: analysis.commitTypes,
      status: 'completed',
      generatedAt: new Date()
    });
    
    console.log(`报告 ${reportId} 生成完成`);
    
  } catch (error) {
    console.error(`报告生成失败 ${reportId}:`, error);
    
    // 更新报告状态为失败
    try {
      const report = await AnalysisReport.findByPk(reportId);
      if (report) {
        await report.update({
          status: 'failed',
          aiSummary: `报告生成失败: ${error.message}`
        });
      }
    } catch (updateError) {
      console.error('更新报告状态失败:', updateError);
    }
  }
}

// 提取基础URL（移除项目路径）
function extractBaseUrl(url) {
  try {
    const urlObj = new URL(url);
    // 如果是GitLab项目URL，提取到域名部分
    const pathParts = urlObj.pathname.split('/').filter(part => part);
    if (pathParts.length >= 2) {
      // 看起来像是项目路径 (username/project)，移除路径
      return `${urlObj.protocol}//${urlObj.host}`;
    }
    return url.replace(/\/$/, ''); // 只移除末尾斜杠
  } catch (error) {
    console.warn('URL解析失败，使用原始URL:', url);
    return url.replace(/\/$/, '');
  }
}

// 生成模拟提交数据（当GitLab API不可用时使用）
function generateMockCommits(startDate, endDate) {
  const commits = [];
  const start = new Date(startDate);
  const end = new Date(endDate);
  const days = Math.ceil((end - start) / (1000 * 60 * 60 * 24));
  
  // 生成一些模拟提交
  for (let i = 0; i < Math.min(days * 2, 50); i++) {
    const date = new Date(start.getTime() + Math.random() * (end - start));
    const commitTypes = ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore'];
    const type = commitTypes[Math.floor(Math.random() * commitTypes.length)];
    const messages = {
      feat: ['添加用户登录功能', '实现数据导出功能', '优化界面设计', '添加搜索功能'],
      fix: ['修复登录bug', '解决数据加载问题', '修复内存泄漏', '修复样式问题'],
      docs: ['更新API文档', '添加使用说明', '更新README', '添加代码注释'],
      style: ['优化代码格式', '统一缩进风格', '更新样式文件', '格式化代码'],
      refactor: ['重构用户模块', '优化数据结构', '简化业务逻辑', '提取公共组件'],
      test: ['添加单元测试', '更新测试用例', '修复测试失败', '增加测试覆盖率'],
      chore: ['更新依赖包', '优化构建配置', '清理无用代码', '更新配置文件']
    };
    
    const typeMessages = messages[type];
    const message = typeMessages[Math.floor(Math.random() * typeMessages.length)];
    
    commits.push({
      id: `mock-${i}`,
      short_id: `mock${i}`,
      title: message,
      message: message + '\n\n详细描述信息',
      author_name: '开发者',
      author_email: 'dev@example.com',
      created_at: date.toISOString(),
      stats: {
        additions: Math.floor(Math.random() * 100) + 10,
        deletions: Math.floor(Math.random() * 50) + 5,
        total: Math.floor(Math.random() * 150) + 15
      }
    });
  }
  
  console.log(`生成 ${commits.length} 个模拟提交数据`);
  return commits.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
}

// 静态文件路由
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'index.html'));
});

app.get('/config.html', (req, res) => {
  res.sendFile(path.join(__dirname, 'config.html'));
});

app.get('/reports.html', (req, res) => {
  res.sendFile(path.join(__dirname, 'reports.html'));
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});